home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 …ember: Reference Library / Dev.CD Dec 94.toast / Periodicals / develop / develop Issue 15 / develop 15 code / Floating Windows / Sample Source / eventHandler.c < prev    next >
Encoding:
Text File  |  1994-10-13  |  8.7 KB  |  340 lines  |  [TEXT/MMCC]

  1. /*    MPW C Application skeleton by Dean Yu    */
  2. /*    Event handling routines                    */
  3.  
  4. // If the interfaces aren't included yet, do the standard includes. Otherwise, precompiled headers
  5. // have been loaded already, thank you very much
  6. #ifndef __TYPES__
  7.     #include <Types.h>
  8.     #include <AppleEvents.h>
  9.     #include <Desk.h>
  10.     #include <Dialogs.h>
  11.     #include <Editions.h>
  12.     #include <Events.h>
  13.     #include <Menus.h>
  14.     #include <SegLoad.h>
  15.     #include <TextUtils.h>
  16.     #include <ToolUtils.h>
  17.     #include <Windows.h>
  18. #endif
  19.  
  20. // Not in Metrowerks default precompiled headers
  21. #include <Editions.h>
  22.  
  23. #include "FloaterSample.h"
  24. #include "appleEventHandlers.h"
  25. #include "eventHandler.h"
  26. #include "menuDispatch.h"
  27.  
  28. /*    Routine prototypes    */
  29.  
  30. void    DoMouseEvent (EventRecord *event);
  31. void    DoKeyEvent (EventRecord *event);
  32. void    DoActivateEvent(EventRecord *event);
  33. void    DoUpdateEvent (EventRecord *event);
  34. void    DrawWindowContent(Boolean doFill);
  35. void    DoOSEvent(EventRecord *event);
  36. void    DoHighLevelEvent(EventRecord *event);
  37. void    HandleGenericHighLevelEvent(EventRecord *event);
  38.  
  39. /* Globals */
  40.     
  41. extern Boolean    gDone;                            /* Set to true if user selects Quit */
  42. extern Boolean    gInBackground;                    /* Set to true if app is switched into background */
  43. extern short    gTimeToDialogDismissal;
  44. extern Rect        gDragArea;                        /* Area in which a window can be dragged */
  45. extern Rect        gGrowBounds;                    /* Min and maximum size a window can be sized to */
  46.  
  47.  
  48. /*
  49.     Fatal error alert routine.
  50.     If an error occurs, this routine is called with the error message number
  51.     that message is pulled from the error STR# resource, and displayed in an
  52.     alert.  The application then quits when the user clicks the “OK” button.
  53. */
  54. void        FatalErrorAlert(short    errID)
  55. {
  56.     short    alrtItem;
  57.     Str255    errString;
  58.     
  59.     GetIndString(errString, rFatalErrorStringsID, errID);
  60.     ParamText(errString, nil, nil, nil);
  61.     alrtItem = Alert(rFatalErrorAlertID, nil);
  62.     ExitToShell();
  63. }
  64.  
  65. void    EventLoop()
  66. {
  67.     EventRecord    event;
  68.     DialogPtr    theDialog;
  69.     short        itemHit;
  70.     Boolean        gotEvent;
  71.     
  72.     gDone = false;
  73.     gInBackground = false;
  74.     
  75.     do {
  76.         gotEvent = WaitNextEvent(everyEvent, &event, 15, nil);
  77.         if (gotEvent) {
  78.             if (!IsDialogEvent(&event))
  79.                 HandleEvent(&event);
  80.             else {
  81.                 DialogSelect(&event, &theDialog, &itemHit);
  82.                 if ((itemHit == ok) || (itemHit == cancel))
  83.                     DisposeFindDialog();
  84.                 
  85.                 if (event.what == osEvt)
  86.                     DoOSEvent(&event);
  87.             }
  88.         }
  89.         
  90.         // If we’re in the background, and the find dialog is up, close it after
  91.         // a time to demonstrate what should happen to floating windows in the background.
  92.         
  93.         if ((gInBackground != false) && (gTimeToDialogDismissal > 0)) {
  94.             --gTimeToDialogDismissal;
  95.             if (gTimeToDialogDismissal == 0)
  96.                 DisposeFindDialog();
  97.         }
  98.     } while (!gDone);
  99.     ExitToShell();
  100. }
  101.  
  102. void    HandleEvent(EventRecord    *event)
  103. {
  104.     switch (event->what) {
  105.         case mouseDown:            DoMouseEvent(event);
  106.                                 break;
  107.         case keyDown:
  108.         case autoKey:            DoKeyEvent(event);
  109.                                 break;
  110.         case activateEvt:        DoActivateEvent(event);
  111.                                 break;
  112.         case updateEvt:            DoUpdateEvent(event);
  113.                                 break;
  114.         case osEvt:                DoOSEvent(event);
  115.                                 break;
  116.         case kHighLevelEvent:    DoHighLevelEvent(event);
  117.                                 break;
  118.                                                         
  119.     }
  120. }
  121.  
  122. void    DoMouseEvent(EventRecord *event)
  123. {
  124.     short        part;
  125.     long        growResult;
  126.     WindowRef    whichWindow;
  127.     WindowRef    frontWindow;
  128.     
  129.     part = FindWindow(event->where, (WindowPtr *)&whichWindow);
  130.     switch (part) {
  131.         case inDesk:        break;
  132.         case inMenuBar:     DoMenuCommand(MenuSelect(event->where));
  133.                             break;
  134.         case inSysWindow:    SystemClick(event, (WindowPtr) whichWindow);
  135.                             break;
  136.         case inContent:        frontWindow = (WindowRef) FrontWindow();
  137.                             if ((GetWindowKind(frontWindow) == dialogKind) &&
  138.                                 (whichWindow != frontWindow))
  139.                                     SysBeep(1);
  140.                             else
  141.                                 if (whichWindow != frontWindow)
  142.                                     SelectReferencedWindow(whichWindow);
  143.                             break;
  144.         case inDrag:        frontWindow = (WindowRef) FrontWindow();
  145.                             if ((GetWindowKind(frontWindow) == dialogKind) &&
  146.                                 (whichWindow != frontWindow))
  147.                                     SysBeep(1);
  148.                             else
  149.                                 DragReferencedWindow(whichWindow, event->where, &gDragArea);
  150.                             break;
  151.         case inGrow:        growResult = GrowWindow((WindowPtr) whichWindow, event->where, &gGrowBounds);
  152.                                 SizeWindow((WindowPtr) whichWindow, growResult & 0x0000FFFF, (growResult & 0xFFFF0000) >> 16, true);
  153.                             break;
  154.         case inGoAway:        if (TrackGoAway((WindowPtr) whichWindow, event->where)) {
  155.                                 DisposeWindowReference(whichWindow);
  156.                                 if (FrontNonFloatingWindow() == nil)
  157.                                     DisableItem(GetMHandle(rFileMenuID), kCloseItem);
  158.                             }
  159.                             break;
  160.         case inZoomIn:
  161.         case inZoomOut:        break;
  162.     }
  163. }
  164.  
  165. void    DoKeyEvent(EventRecord *event)
  166. {
  167.     long    theKey;
  168.     
  169.     theKey = event->message & charCodeMask;
  170.     if ((event->modifiers & cmdKey) && (event->what == keyDown))
  171.         DoMenuCommand(MenuKey((char) theKey));
  172. }
  173.  
  174. void DoActivateEvent(EventRecord *event)
  175. {
  176.     Boolean    activating = false;
  177.     
  178.     if (GetWindowKind((WindowRef) event->message) != dialogKind) {
  179.         if (event->modifiers & activeFlag)
  180.             activating = true;
  181.         
  182.         DebugStr("\pGot activate from event loop.");
  183.         
  184.         ActivateEventHandler((WindowRef) event->message, activating);
  185.     }
  186. }
  187.  
  188. pascal void ActivateEventHandler(WindowRef theWindow, Boolean activateWindow)
  189. {
  190.     GrafPtr    currentPort;
  191.     
  192.     GetPort(¤tPort);
  193.     SetPort((GrafPtr) theWindow);
  194.     
  195.     DrawWindowContent(activateWindow);
  196.     
  197.     if (activateWindow == false)
  198.         SetPort(currentPort);
  199. }
  200.  
  201. pascal void    RecordingFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
  202. {
  203.     GrafPtr        currentPort;
  204.     PicHandle    recordingControlsPicture;
  205.     short        whichPicture;
  206.     
  207.     GetPort(¤tPort);
  208.     SetPort((GrafPtr) theWindow);
  209.     
  210.     if (activateWindow == true)
  211.         whichPicture = 128;
  212.     else
  213.         whichPicture = 129;
  214.     recordingControlsPicture = GetPicture(whichPicture);
  215.     
  216.     DrawPicture(recordingControlsPicture, &((**recordingControlsPicture).picFrame));
  217.     SetWindowPic((WindowPtr) theWindow, recordingControlsPicture);
  218.     
  219.     if (activateWindow == false)
  220.         SetPort(currentPort);
  221. }
  222.  
  223. pascal void    ToolsFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
  224. {
  225.     GrafPtr        currentPort;
  226.     PicHandle    toolsPicture;
  227.     short        whichPicture;
  228.     
  229.     GetPort(¤tPort);
  230.     SetPort((GrafPtr) theWindow);
  231.     
  232.     if (activateWindow == true)
  233.         whichPicture = 130;
  234.     else
  235.         whichPicture = 131;
  236.     toolsPicture = GetPicture(whichPicture);
  237.     
  238.     DrawPicture(toolsPicture, &((**toolsPicture).picFrame));
  239.     SetWindowPic((WindowPtr) theWindow, toolsPicture);
  240.     
  241.     if (activateWindow == false)
  242.         SetPort(currentPort);
  243. }
  244.  
  245. void    DoUpdateEvent(EventRecord *event)
  246. {
  247.     WindowPtr    theWindow = (WindowPtr) event->message;
  248.     
  249.     SetPort(theWindow);
  250.     BeginUpdate(theWindow);
  251.         EraseRect(&(theWindow->portRect));
  252.         DrawWindowContent(theWindow == (WindowPtr)FrontNonFloatingWindow());
  253.     EndUpdate(theWindow);
  254. }
  255.  
  256. void    DrawWindowContent(Boolean doFill)
  257. {
  258.     Rect    tempRect;
  259.  
  260.     SetRect(&tempRect, 5, 5, 50, 50);
  261.     
  262.     if (doFill == true)
  263.         FillRect(&tempRect, &(qd.black));
  264.     else {
  265.         FrameRect(&tempRect);
  266.         InsetRect(&tempRect, 1, 1);
  267.         EraseRect(&tempRect);
  268.     }
  269. }
  270.  
  271. void    DoOSEvent(EventRecord *event)
  272. {
  273.     switch ((event->message >> 24) & 0xFF) {
  274.         case mouseMovedMessage:        break;
  275.         case suspendResumeMessage:    if (event->message & resumeFlag) {
  276.                                         gInBackground = false;
  277.                                         gTimeToDialogDismissal = 0;
  278.                                         DisableItem(GetMHandle(rEditMenuID), 0);
  279.                                         DrawMenuBar();
  280.                                         ResumeFloatingWindows();
  281.                                         SetCursor(&qd.arrow);
  282.                                     }
  283.                                     else {
  284.                                         gInBackground = true;
  285.                                         if (GetWindowKind((WindowRef) FrontWindow()) == dialogKind)
  286.                                             gTimeToDialogDismissal = 5;
  287.                                         SuspendFloatingWindows();
  288.                                     }
  289.                                     break;
  290.     }
  291. }
  292.  
  293.  
  294. /*    Handle high level events */
  295.  
  296. void    DoHighLevelEvent(EventRecord *event)
  297. {
  298.     OSErr    AEProcessResult;
  299.     
  300.     switch    (event->message) {
  301.         case kCoreEventClass:    AEProcessResult = AEProcessAppleEvent(event);    /*    Handle core AppleEvents */
  302.                                 break;
  303.         case rSectionType:        break;                                            /*    Handle Edition Manager AppleEvents */
  304.         default:                HandleGenericHighLevelEvent(event);                /*    Other high level events */
  305.                                 break;
  306.     }
  307. }
  308.  
  309. void    HandleGenericHighLevelEvent(EventRecord *event)
  310. {
  311.     TargetID    eventSenderInfo;
  312.     unsigned    long eventIdentifier;
  313.     Ptr            dataBuffer;
  314.     unsigned    long dataSize;
  315.     OSErr    HLEventError;
  316.     
  317.     dataSize = 0;
  318.     dataBuffer = nil;
  319.     HLEventError = AcceptHighLevelEvent(&eventSenderInfo, &eventIdentifier, dataBuffer, &dataSize);
  320.     
  321.     /*
  322.         Since we don’t know how much data is coming in, call AcceptHighLevelEvent once to
  323.         find out how much data was sent, then use create a new buffer large enough to hold
  324.         all the data, then call AcceptHighLevelEvent again to get the data.
  325.     */
  326.     
  327.     if (HLEventError == bufferIsSmall) {
  328.         dataBuffer = NewPtr(dataSize);
  329.         HLEventError = AcceptHighLevelEvent(&eventSenderInfo, &eventIdentifier, dataBuffer, &dataSize);
  330.     }
  331.         
  332.     /*    Dispatch the high level event to the proper routine depending on the message class */
  333.     
  334.     switch    (event->message) {
  335.     }
  336.     
  337.     if (dataBuffer)
  338.         DisposPtr(dataBuffer);
  339. }
  340.